Список Задач + Dependency Inversion Principle
➡️Ссылка на репозиторий с кодом этого урока
Улучшаем приложение
Сделаем его по-настоящему гибким, применив принцип инверсии зависимостей
Dependency Inversion Principle из SOLID
Проблема
ToDoViewModel напрямую создает экземпляр
final StorageService _storageService = StorageService();
Это создает жесткую связь !
ViewModel знает о конкретной реализации сервиса.
Если мы захотим заменить SharedPreferences на SQLite или любое другое хранилище, то придется изменять код самого ToDoViewModel, что нарушает принцип открытости/закрытости (2 принцип SOLID).
Решение
- Интерфейсы (Абстракции): Создаём "контракт" (
interface), который описывает, что должен делать сервис хранения (сохранитьЗадачи,загрузитьЗадачи), но не как он это делает. - Внедрение зависимостей (Dependency Injection - DI): Вместо того чтобы
ToDoViewModelсам создавал нужный ему сервис, будем "внедрять" (передавать) ему уже готовый объект снаружи (через конструктор). ViewModel будет зависеть не от конкретного класса, а от интерфейса.
Это и есть инверсия зависимостей: высокоуровневые модули (ToDoViewModel) не должны зависеть от низкоуровневых (SharedPreferencesService), оба должны зависеть от абстракций (IStorageService).